package wint.mvc.view.types;

import java.io.IOException;
import java.io.Writer;

import wint.core.config.Constants;
import wint.lang.exceptions.FlowDataException;
import wint.lang.magic.MagicMap;
import wint.lang.utils.StringUtil;
import wint.lang.utils.TargetUtil;
import wint.mvc.flow.InnerFlowData;
import wint.mvc.flow.StatusCodes;
import wint.mvc.template.Context;
import wint.mvc.template.DefaultContext;
import wint.mvc.template.LoadTemplateService;
import wint.mvc.template.TemplateRender;

/**
 * @author pister 2012-3-4 06:53:24
 */
public class TemplateViewRender extends AbstractViewRender {

	public static final String TYPE_NAME = "template";
	
	private LoadTemplateService loadTemplateService;
	
	private String layoutName;
	
	private String pageContentName;
	
	public String getViewType() {
		return TYPE_NAME;
	}

	@Override
	public void init() {
		super.init();
		loadTemplateService = serviceContext.getService(LoadTemplateService.class);
		MagicMap properties = serviceContext.getConfiguration().getProperties();
		layoutName = properties.getString(Constants.PropertyKeys.TEMPLATE_LAYOUT, Constants.Defaults.TEMPLATE_LAYOUT);
		pageContentName = properties.getString(Constants.PropertyKeys.PAGE_CONTENT_NAME, Constants.Defaults.PAGE_CONTENT_NAME);
	}

	public void render(Context context, InnerFlowData flowData, String target, String moduleType) {
		Context innerContext = flowData.getInnerContext();
		Context targetContext;
		if (innerContext != null) {
			targetContext = new DefaultContext(innerContext);
			targetContext.putContext(context);
		} else {
			targetContext = context;
		}
		
		target = TargetUtil.normalizeTarget(target);
		TemplateRender page = loadTemplateService.loadTemplate(target, targetContext, moduleType);
		if (page == null) {
			if (onResourceNotFound(flowData, target)) {
				return;
			}
		}
		String pageContent = page.render();
		Context layoutContext = targetContext.copyMe();
		
		String layoutTarget = flowData.getLayout();
		TemplateRender layout;
		if (!StringUtil.isEmpty(layoutTarget)) {
			layout = loadTemplateService.loadTemplate(layoutTarget, layoutContext, layoutName);
		} else {
			layout = loadTemplateService.loadTemplate(target, layoutContext, layoutName);
		}
		String content;
		if (layout != null) {
			layoutContext.put(pageContentName, pageContent);
			content = layout.render();
		} else {
			content = pageContent;
		}
		writeContent(flowData.getWriter(), content);
	}
	
	protected boolean onResourceNotFound(InnerFlowData flowData, String target) {
		flowData.setStatusCode(StatusCodes.SC_NOT_FOUND);
		return true;
	}

	private void writeContent(Writer writer, String content) {
		try {
			writer.write(content);
			writer.close();
		} catch (IOException e) {
			throw new FlowDataException(e);
		}
	}
	
}
